package com.my.ribbon.rule;

import com.my.ribbon.predicate.DiscoveryEnabledPredicate;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import org.springframework.util.Assert;

import java.util.List;

/**
 * @author timo 2021/3/23
 */
public abstract class DiscoveryEnabledRule extends PredicateBasedRule {
    private final CompositePredicate predicate;

    public DiscoveryEnabledRule(DiscoveryEnabledPredicate discoveryEnabledPredicate) {
        Assert.notNull(discoveryEnabledPredicate, "Parameter 'discoveryEnabledPredicate' can't be null");
        this.predicate = this.createCompositePredicate(discoveryEnabledPredicate, new AvailabilityPredicate(this, (IClientConfig)null));
    }

    @Override
    public AbstractServerPredicate getPredicate() {
        return this.predicate;
    }

    @Override
    public Server choose(Object key) {
        ILoadBalancer lb = this.getLoadBalancer();
        List<Server> allServers = lb.getAllServers();
        List<Server> serverList = this.filterServers(allServers);
        return (Server)this.getPredicate().chooseRoundRobinAfterFiltering(serverList, key).orNull();
    }

    public abstract List<Server> filterServers(List<Server> serverList);

    private CompositePredicate createCompositePredicate(DiscoveryEnabledPredicate discoveryEnabledPredicate, AvailabilityPredicate availabilityPredicate) {
        CompositePredicate.Builder builder = CompositePredicate.withPredicates(new AbstractServerPredicate[]{discoveryEnabledPredicate, availabilityPredicate});
        return builder.build();
    }
}
